<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <title>面向过程的柱状图</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link type="text/css" rel="stylesheet" href="./index.css">
  <script src="https://cdn.staticfile.org/konva/2.6.0/konva.js"></script>
</head>
  <body>
    <!-- <canvas id="myCanvas" width="600" height="600">
      你的浏览器不支持canvas，请升级浏览器
    </canvas> -->
    <div id="con"></div>
  </body>
</html>

<script>
  (function(){
    let data = [
      {name:'前端', value: '.8', color: 'green'},
      {name:'PHP', value: '.3', color: 'blue'},
      {name:'Java', value: '.7', color: 'red'},
      {name:'UI', value: '.9', color: 'orange'},
      {name:'IOS', value: '.4', color: 'purple'},
      {name:'Android', value: '.9', color: 'pink'},
    ]

    // 创建舞台
    let stage = new Konva.Stage({
      container: 'con', // 放到哪个div的容器内显示
      width: window.innerWidth, // 等于屏幕宽度
      height: window.innerHeight // 等于屏幕高度
    })
    let layer = new Konva.Layer();// 创建一个层
    stage.add( layer ); // 把层添加到舞台上去

    // 设置起始xy坐标，以百分比，这样兼容各平台显示
    let x0 = 1/8 * stage.width();
    let y0 = 3/4 * stage.height();
    // 设置柱状图最大宽高度
    let width = 3/4 * stage.width();
    let height = 1/2 * stage.height();

    // 创建底线条
    let bsLine = new Konva.Line({
      // 前二参数起始坐标，后面画到指定坐标位置处（可以无限画）
      points: [x0,y0, x0+width, y0],
      stroke: 'lightgreen', // 线的颜色
      strokeWidth: 2, // 线的宽度
    })
    layer.add(bsLine); // 添加到层上去

    // 创建一个组，定义一串数据参数
    let group = new Konva.Group({
      x:x0,
      y:y0,
    })
    // 定义矩形每个占的空间
    let rectWidth = width / data.length;
    //循环创建每个柱状图数据
    data.forEach( (item,index) => {
      // 创建矩形-柱状图
      let react = new Konva.Rect({
        // x坐标位置占矩形位置在加二边空距，我是定了四分之一
        x: (1/4 + index) * rectWidth,
        y: - (item.value * height), // 调整每个y轴位置
        width: rectWidth/2, // 画宽度占一半，其它留空
        // 因为高度是向下的，所以要把y轴向上移动
        height: item.value * height, // 矩形高度，最大宽度*占比
        fill: item.color,
        opacity: .8,
        cornerRadius: 25, //圆角
      })
      group.add(react); // 添加到组,会继承组内的参数

      // 把百分比文字放到 柱状图的顶部文字
      let text = new Konva.Text({
        x: (index * rectWidth),
        y: - (item.value * height) - 14, // 调整每个y轴位置
        fontSize: 14, // 字体大小
        width: rectWidth, // 宽度配合文字居中
        align: 'center',
        fill: item.color, // 颜色
        name: 'textPercent',
        text: `${item.value*100}%` // 内容
      })
      group.add(text); // 添加到组

      // 底部文字内容
      let textBottom = new Konva.Text({
        x: (1/4+index) * rectWidth,
        y: 0, // 调整每个y轴位置
        fontSize: 14, // 字体大小
        width: rectWidth, // 宽度配合文字居中
        // align: 'center',
        fill: item.color, // 颜色
        rotation: 30, // 旋转
        text: item.name // 内容
      })
      group.add(textBottom); // 添加到组
    });

    layer.add(group); // 把组内的图添加到层上去

    // 把层渲染到舞台上
    layer.draw();

    // 做一个动画效果事件
    // 在舞台上点击任何区域的时候都会触发此事件
    stage.on('contentClick', ()=>{
      // 拿到所有矩形,让柱状图进行动画展示
      layer.find('Rect').each( (item,index)=>{
        // 让状态图中所有矩形 高0,y0
        // 在konva中不传入参数就是读取值,传入就是改变值
        item.y(0); // 设置每个矩形的y轴,因为在组中,所以写0继承了值
        item.height(0);
        // 动画显示到初始状态
        item.to({
          duration: 2,
          y: - (data[index].value * height),
          height: data[index].value * height,
        })
      });
      // 拿到顶部文字
      layer.find('.textPercent').each( (item,index)=>{
        item.y(0 - 14); // 设置y轴,确保一直在柱状图顶部固定
        // 动画显示到初始状态
        item.to({
          duration: 2,
          y: - (data[index].value * height) -14,
        })
      });
    })
  })()
</script>

